/**  
* @Title: TokenUtils.java
* @Package com.lemon.utils
* @Description: (一句话阐述):
* @author Ran_cc
* @date 2018年5月13日
* @version V1.0  
*/
package com.lemon.utils;

import java.security.Key;
import java.util.Date;

import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lemon.conf.MyException;
import com.lemon.conf.MyYml;
import com.lemon.conf.content.SpringContextUtil;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

/**
 * <p>Title: 生成token </p>
 * <p>Description: </p>
 * <p>Company: </p>
 * @author Ran_cc
 * @date 2018年5月13日
 * @版本 V 1.0 
 */

public class TokenUtils {
	private   Logger log = LoggerFactory.getLogger(this.getClass());
	
	//通过springcontext上下文读取配置文件中的自定义内容 . 
	public  static  MyYml yml = (MyYml)SpringContextUtil.getBean("myYml");
	
    /**
     * 签名秘钥
     */
    public static final String SECRET = yml.getSecretKey();
    /**
     * 生成token
     * @param id 传入的要加入令牌的参数  一般传入userName , 
     * @return
     */
    public static String createJwtToken(String id){
        String issuer = yml.getIssuer();
        String subject = yml.getSubject();
        
    	/*String issuer = "www.lemon-sea.com";
        String subject = "346533165@qq.com";*/
		//24小时*7天
        long ttlMillis = Long.parseLong(yml.getDuiTime())*24*60*60*1000L; ///System.currentTimeMillis(); 
        return createJwtToken(id, issuer, subject, ttlMillis);
    }

    /**
     * 生成Token
     * 
     * @param id
     *            编号
     * @param issuer
     *            该JWT的签发者，是否使用是可选的
     * @param subject
     *            该JWT所面向的用户，是否使用是可选的；
     * @param ttlMillis
     *            签发时间
     * @return token String
     */
    public static String createJwtToken(String id, String issuer, String subject, long ttlMillis) {

        // 签名算法 ，将对token进行签名
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        // 生成签发时间
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        // 通过秘钥签名JWT
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(SECRET);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());

        // Let's set the JWT Claims
        JwtBuilder builder = Jwts.builder().setId(id)
            .setIssuedAt(now)
            .setSubject(subject)
            .setIssuer(issuer)
            .signWith(signatureAlgorithm, signingKey);

        // if it has been specified, let's add the expiration
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date exp = new Date(expMillis);
            builder.setExpiration(exp);
        }

        // Builds the JWT and serializes it to a compact, URL-safe string
        return builder.compact();

    }

    // Sample method to validate and read the JWT
    public static Claims parseJWT(String jwt) {
        // This line will throw an exception if it is not a signed JWS (as expected)
        Claims claims = null;
		try {
			claims = Jwts.parser()
			    .setSigningKey(DatatypeConverter.parseBase64Binary(SECRET))
			    .parseClaimsJws(jwt).getBody();
		} catch (ExpiredJwtException e) {
			//将错误信息输出到日志文件
			MyException.writeErr(e,"登陆令牌过期");
		} 
        return claims;
    }

    public static void main(String[] args) {
        System.out.println(TokenUtils.createJwtToken("admin-张三-8888"));
    }
}
